#ifndef _MFnDagNode
#define _MFnDagNode
//-
// ==========================================================================
// Copyright (C) 1995 - 2006 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MFnDagNode
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES


#include <maya/MFnDependencyNode.h>
#include <maya/MObject.h>
#include <stdlib.h>

// ****************************************************************************
// DECLARATIONS

class MMatrix;
class MDagPath;
class MDagPathArray;
class MBoundingBox;
class MStringArray;

// ****************************************************************************
// CLASS DECLARATION (MFnDagNode)

//! \ingroup OpenMaya MFn
//! \brief DAG Node Function Set. 
/*!
Provides methods for attaching Function Sets to, querying, and adding
children to DAG Nodes. Particularly useful when used in conjunction
with the DAG Iterator class (MItDag).

The MFnDagNode function set is used to query and set the attributes of
nodes in the DAG (Directed Acyclic Graph).  The DAG is a graph that
describes the hierarchy of the objects in the model.  At each level of
the hierarchy there is a four by four transformation matrix that
affects all of the objects beneath it in the DAG.

In the DAG, geometry objects (also known as shapes) do not have
transformation information associated with them.  Only transform
nodes have actual transform matrices (see MFnTransform).

Each node that exists in the DAG is also a dependency node that
exists in the dependency graph.  This makes it possible to control
the attributes of a DAG node based on calculations performed by
dependency nodes.

There are two ways to specify a DAG node in Maya.  The first is
to use an MObject handle, which acts as a pointer to a specific
node in the DAG.  Given only an MObject, it is not possible to do
world space operations on a DAG node because there may be more
than one path through the DAG to any given node.  In other words,
it is not possible to identify a particular instance only given
an MObject.

In many cases it is preferable to use a DAG path (MDagPath) to specify
a DAG node.  A DAG path always refers to a specific instance of an
object.  This makes it possible to perform unambiguous world space
transformations.

It is also possible to iterate over the nodes in the DAG using a
DAG iterator (MItDag).
*/
class OPENMAYA_EXPORT MFnDagNode : public MFnDependencyNode
{
#ifdef DISALLOW_COPY_CONSTRUCTOR
	declareMinimalMFnDisallowCopyConstructor( MFnDagNode );
#else
	declareMinimalMFn( MFnDagNode );
#endif

public:

	//! Anonymous enum to store constant values.
	enum {
		//! used by addChild to indicate the next empty position in the list.
		kNextPos = 0xff
	};

	MFnDagNode();
	MFnDagNode( MObject & object, MStatus * ret = NULL );
	MFnDagNode( const MDagPath & object, MStatus * ret = NULL );

    MObject         create( const MTypeId &typeId,
							MObject &parent = MObject::kNullObj,
							MStatus* ReturnStatus = NULL );
    MObject         create( const MTypeId &typeId,
							const MString &name,
							MObject &parent = MObject::kNullObj,
							MStatus* ReturnStatus = NULL );

    MObject         create( const MString &type,
							MObject &parent = MObject::kNullObj,
							MStatus* ReturnStatus = NULL );
    MObject         create( const MString &type,
							const MString &name,
							MObject &parent = MObject::kNullObj,
							MStatus* ReturnStatus = NULL );

	unsigned int	parentCount( MStatus * ReturnStatus = NULL ) const;
	MObject 		parent( unsigned int i,
							MStatus * ReturnStatus = NULL ) const;
	MStatus	        addChild( MObject & child, unsigned int index = kNextPos,
							  bool keepExistingParents = false );
	MStatus			removeChild( MObject & child );
	MStatus			removeChildAt( unsigned int index );
	unsigned int    childCount(  MStatus * ReturnStatus = NULL ) const;
	MObject 	    child( unsigned int i,
						   MStatus * ReturnStatus = NULL ) const;
	MObject  		dagRoot( MStatus * ReturnStatus = NULL );
	bool			hasParent( const MObject & node,
							   MStatus * ReturnStatus = NULL ) const;
	bool			hasChild (const MObject& node,
							  MStatus * ReturnStatus = NULL ) const;
	bool			isChildOf (const MObject& node,
							   MStatus * ReturnStatus = NULL ) const;
	bool			isParentOf (const MObject& node,
								MStatus * ReturnStatus = NULL ) const;
	bool			inUnderWorld ( MStatus * ReturnStatus = NULL ) const;
	bool			inModel ( MStatus * ReturnStatus = NULL ) const;
	bool			isInstanceable( MStatus* ReturnStatus=NULL ) const;
	MStatus			setInstanceable( const bool how );
	bool			isInstanced( bool indirect = true,
						           MStatus * ReturnStatus = NULL ) const;
	bool			isInstancedAttribute( const MObject& attr,
									MStatus * ReturnStatus = NULL ) const;
	unsigned int	instanceCount( bool total,
						           MStatus * ReturnStatus = NULL ) const;
	MObject			duplicate( bool instance = false,
					           bool instanceLeaf = false,
					           MStatus * ReturnStatus = NULL ) const;
	
	// BUG 301927: Making path methods const --RJ
	MStatus		    getPath( MDagPath& path ) const;
	MStatus		    getAllPaths( MDagPathArray& paths ) const;
	MString         fullPathName(MStatus *ReturnStatus = NULL) const;
    MString         partialPathName(MStatus *ReturnStatus = NULL) const;

	MMatrix			transformationMatrix( MStatus * ReturnStatus = NULL ) const;

	bool            isIntermediateObject( MStatus * ReturnStatus = NULL ) const;
	MStatus         setIntermediateObject( bool isIntermediate );

	int				objectColor( MStatus * ReturnStatus = NULL ) const;
	MStatus			setObjectColor( int color );
	bool			usingObjectColor ( MStatus * ReturnStatus = NULL ) const;
	MStatus			setUseObjectColor( bool useObjectColor );

	MBoundingBox	boundingBox( MStatus * ReturnStatus = NULL ) const;

	MDagPath		dagPath( MStatus * ReturnStatus = NULL ) const;
	virtual MStatus setObject( const MDagPath & path );
 	virtual MStatus setObject( MObject & object );

	// Obsolete
	MObject         model( MStatus * ReturnStatus = NULL ) const;

	// Internal
	MStatus			objectGroupComponent( unsigned int groupId,

										  MStringArray & );

BEGIN_NO_SCRIPT_SUPPORT:

    //!	No script support
	MFnDagNode( const MObject & object, MStatus * ret = NULL );

	//!	No script support
 	virtual MStatus setObject( const MObject & object );

END_NO_SCRIPT_SUPPORT:

protected:

	void * f_path;
	void * f_xform;

	void * f_data1;
	void * f_data2;

private:
// No private members
};

#define declareDagMFn( MFnClass, MFnParentClass )			  	 	\
	declareMinimalMFn( MFnClass );								 	\
	public:	        											 	\
		MFnClass();											     	\
		MFnClass( MObject & object, MStatus * ret = NULL );	   	 	\
		MFnClass( const MDagPath & object, MStatus * ret = NULL )

#define declareDagMFnConstConstructor( MFnClass, MFnParentClass )	\
		MFnClass( const MObject & object, MStatus * ret = NULL )

#endif /* __cplusplus */
#endif /* _MFnDagNode */
